package com.homedo.odin.solution.service;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.homedo.core.common.base.dto.Meta;
import com.homedo.core.common.exception.BizException;
import com.homedo.core.common.util.BeanUtils;
import com.homedo.core.common.util.ParamCheckUtil;
import com.homedo.core.common.util.StringUtil;
import com.homedo.odin.solution.contract.oms.UserSafeReq;
import com.homedo.odin.solution.contract.oms.ValidateUserSafeReq;
import com.homedo.odin.solution.dao.UserBasicMapper;
import com.homedo.odin.solution.dao.UserSafeMapper;
import com.homedo.odin.solution.enumcode.basic.ErrorCodeEnum;
import com.homedo.odin.solution.enumcode.usersafe.BizCodeEnum;
import com.homedo.odin.solution.enumcode.usersafe.UserSafeSourceEnum;
import com.homedo.odin.solution.enumcode.usersafe.UserSafeStatusEnum;
import com.homedo.odin.solution.model.entity.UserBasic;
import com.homedo.odin.solution.model.entity.UserSafe;
import com.homedo.odin.solution.model.request.mng.MngUserSafeImportReq;
import com.homedo.odin.solution.model.request.mng.MngUserSafeReqsListRequestBean;
import com.homedo.odin.solution.model.request.pc.PcUserSafeRequestBean;
import com.homedo.odin.solution.model.response.mng.MngBatchInputResponse;
import com.homedo.odin.solution.model.response.mng.MngUserSafePageResponseBean;
import com.homedo.odin.solution.model.response.mng.MngUserSafeResponseBean;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p> 白名单  服务实现类 </p>
 *
 * @author ZhangLei
 * @date 2018-05-22
 * @Description:
 */
@Service
public class UserSafeServiceImpl extends ServiceImpl<UserSafeMapper, UserSafe> {

    private static final Logger logger = LoggerFactory.getLogger(UserSafeServiceImpl.class);

    @Autowired
    private UserBasicMapper userBasicMapper;
    @Autowired
    private PoiServiceImpl poiService;

    public UserSafe selectOne(UserSafe safe) {
        return baseMapper.selectOne(safe);
    }

    /**
     * 批量删除
     */
    public void deleteUserSafe(String ids, String biz_code) {
        if (StringUtils.isEmpty(biz_code)) {
            throw new BizException(Meta.CODE_451.getCode(), Meta.CODE_451.getMsg());
        }
        baseMapper.deleteUserSafe(ids, biz_code);
    }

    /**
     * @Description: 白名单审核
     * @Author: liyi
     * @Date:
     */
    public void check(UserSafeReq requestBean, String bizCode, Integer status) {
        Long id = requestBean.getId();
        UserSafe userSafe = selectById(id);
        if (userSafe == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "不存在该白名单");
        }
        if (!BizCodeEnum.dbValueExist(bizCode)) {
            throw new BizException(Meta.CODE_451.getCode(), "所属业务类型不符");
        }
        if (!UserSafeStatusEnum.dbValueExist(status)) {
            throw new BizException(Meta.CODE_451.getCode(), "审核状态不符");
        }
        userSafe.setStatus(status);
        userSafe.setReason(requestBean.getReason());
        userSafe.setModifiedTime(new java.util.Date());
        userSafe.setOperator(requestBean.getOperator());
        updateById(userSafe);
    }

    /**
     * @Description: 验证白名单用户是否存在
     * @Author: liyi
     */
    public boolean validateUserSafe(ValidateUserSafeReq requestBean, String bizCode) {

        if (StringUtils.isEmpty(bizCode)) {
            throw new BizException(Meta.CODE_451.getCode(), Meta.CODE_451.getMsg());
        }

        if (StringUtil.isEmpty(requestBean.getMobile()) && StringUtil.isEmpty(requestBean.getUserName())) {
            throw new BizException(Meta.CODE_451.getCode(), "请输入用户名或手机号");
        }
        if (StringUtils.isNotBlank(requestBean.getMobile()) && StringUtils.isNotBlank(requestBean.getUserName())) {
            String mobile = requestBean.getMobile();
            String user_name = requestBean.getUserName();
            List<UserSafe> userSafesByMobileAndUserNameList = baseMapper
                    .selectListByUserNameOrMobile(bizCode, UserSafeStatusEnum.APPROVED.getDbValue(), user_name, mobile);
            return (userSafesByMobileAndUserNameList.size() > 0);
        } else if (StringUtils.isNotBlank(requestBean.getMobile())) {
            String mobile = requestBean.getMobile();
            UserSafe queryUserSafe = new UserSafe();
            queryUserSafe.setMobile(mobile);
            queryUserSafe.setStatus(UserSafeStatusEnum.APPROVED.getDbValue());
            queryUserSafe.setBizCode(bizCode);
            List<UserSafe> userSafesByMobileList = baseMapper.selectListByUserSafe(queryUserSafe);
            return (userSafesByMobileList.size() > 0);
        } else if (StringUtils.isNotBlank(requestBean.getUserName())) {
            String userName = requestBean.getUserName();
            UserSafe queryUserSafe = new UserSafe();
            queryUserSafe.setUserName(userName);
            queryUserSafe.setStatus(UserSafeStatusEnum.APPROVED.getDbValue());
            queryUserSafe.setBizCode(bizCode);
            List<UserSafe> userSafesByUserNameList = baseMapper.selectListByUserSafe(queryUserSafe);
            return (userSafesByUserNameList.size() > 0);
        }
        return false;
    }

    /**
     * 前台申请白名单
     */
    public boolean userSafeApply(PcUserSafeRequestBean requestBean, String bizCode) {
        if (!BizCodeEnum.dbValueExist(bizCode)) {
            throw new BizException(Meta.CODE_451.getCode(), "所属业务类型不符");
        }
        UserBasic queryUserBasic = new UserBasic();
        queryUserBasic.setUserId(requestBean.getUserId());
        UserBasic userBasic = userBasicMapper.selectOne(queryUserBasic);
        if (userBasic == null) {
            throw new BizException(ErrorCodeEnum.NotExist.getDbValue(), "不存在该用户");
        }

        //判读是否申请过白名单
        ValidateUserSafeReq validateUserSafeReq = new ValidateUserSafeReq();
        validateUserSafeReq.setMobile(userBasic.getMobile());
        validateUserSafeReq.setUserName(userBasic.getUserName());
        if (validateUserSafe(validateUserSafeReq, bizCode)) {
            throw new BizException(ErrorCodeEnum.IsExist.getDbValue(), "已存在白名单记录");
        }
        //根据userId判断白名单是否存在
        UserSafe queryUserSafe = new UserSafe();
        queryUserSafe.setUserId(requestBean.getUserId());
        queryUserSafe.setBizCode(BizCodeEnum.PRODUCT.getDbValue());
        UserSafe userSafeIsHad = selectOne(queryUserSafe);
        if (userSafeIsHad != null) {
            throw new BizException(ErrorCodeEnum.IsExist.getDbValue(), "已存在白名单记录");
        }

        UserSafe userSafe = BeanUtils.transfrom(UserSafe.class, requestBean);
        userSafe.setBizCode(bizCode);
        userSafe.setUserId(userBasic.getUserId());
        userSafe.setUserName(userBasic.getUserName());
        userSafe.setCreatedTime(new java.util.Date());
        userSafe.setMobile(userBasic.getMobile());
        userSafe.setModifiedTime(new java.util.Date());
        userSafe.setOperator(userBasic.getUserName());
        userSafe.setSource(UserSafeSourceEnum.FRONT_APPLY.getDbValue());
        userSafe.setStatus(UserSafeStatusEnum.TO_AUDIT.getDbValue());
        return insert(userSafe);
    }

    /**
     * Mng_白名单列表
     */
    public MngUserSafePageResponseBean userSafeList(MngUserSafeReqsListRequestBean requestBean, String bizCode) {

        if (!BizCodeEnum.dbValueExist(bizCode)) {
            throw new BizException(Meta.CODE_451.getCode(), Meta.CODE_451.getMsg());
        }

        PageInfo<MngUserSafeResponseBean> pageInfo = PageHelper
                .startPage(requestBean.getPageNum(), requestBean.getPageSize()).doSelectPageInfo(() ->
                        baseMapper.userSafeList(bizCode, requestBean.getSource(), requestBean.getStatus(),
                                requestBean.getUsernameOrMobile()
                        ));
        if (CollectionUtils.isNotEmpty(pageInfo.getList())) {
            pageInfo.getList().forEach(dbBean -> {
                dbBean.setSourceLabel(UserSafeSourceEnum.getExistDisplayValue(dbBean.getSource()));
                dbBean.setStatusLabel(UserSafeStatusEnum.getExistDisplayValue(dbBean.getStatus()));
            });
        }
        return BeanUtils.transfrom(MngUserSafePageResponseBean.class, pageInfo);
    }

    /**
     * @Description: 导入白名单时解析白名单
     * @Author: liyi
     */
    @Transactional(rollbackFor = {Exception.class})
    public MngBatchInputResponse batchInput(MngUserSafeImportReq requestBean, String bizCode) {

        if (!BizCodeEnum.dbValueExist(bizCode)) {
            throw new BizException(Meta.CODE_451.getCode(), Meta.CODE_451.getMsg());
        }

        MngBatchInputResponse mngBatchInputResponse = new MngBatchInputResponse();
        Long userId = requestBean.getUserId();
        String userName = requestBean.getUserName();
        String url = requestBean.getUrl();
        ParamCheckUtil.checkLongUserId(userId);
        if (org.apache.commons.lang3.StringUtils.isBlank(userName)) {
            throw new BizException(Meta.CODE_451.getCode(), "用户名字不能为空");
        }
        if (org.apache.commons.lang3.StringUtils.isBlank(url)) {
            throw new BizException(Meta.CODE_451.getCode(), "url参数不能为空");
        }

        //下载 ，解析资源
        try {
            List<Meta> metaList = new ArrayList<Meta>();
            Workbook book = poiService.getSheets(url);
            Sheet sheet = book.getSheetAt(0);
            Row TitleRow = sheet.getRow(0);
            int rowNum = sheet.getLastRowNum();
            if (rowNum >= 1) {
                for (int i = 1; i <= rowNum; i++) {
                    Row row = sheet.getRow(i);
                    Cell userNameCell = row.getCell(0);
                    Cell mobileCell = row.getCell(1);
                    if (userNameCell != null) {
                        userNameCell.setCellType(CellType.STRING);
                        String mobileCellValue = "";
                        if (mobileCell != null) {
                            mobileCell.setCellType(CellType.STRING);
                            mobileCellValue = mobileCell.getStringCellValue();
                        }
                        String userNameCellValue = userNameCell.getStringCellValue();
                        //判断逻辑
                        if (analyse(metaList, userNameCellValue, mobileCellValue, bizCode)) {
                            save(requestBean, userNameCellValue, mobileCellValue, bizCode);
                        } else {
                            mngBatchInputResponse.setErrorSize(mngBatchInputResponse.getErrorSize() + 1);
                        }
                    }
                }
            }
            mngBatchInputResponse.setList(metaList);
        } catch (IOException e) {
            logger.error("资源下载解析失败", e);
        }
        return mngBatchInputResponse;
    }

    /**
     * @Description: 过滤白名单用户
     * @Author: liyi
     */
    public boolean analyse(List<Meta> metaList, String userName, String mobile, String bizCode) {
        //用户账号[username]缺失
        if (StringUtils.isEmpty(userName)) {
            metaList.add(new Meta(Meta.CODE_451.getCode(), "用户名缺失"));
            return false;
        }
        //判断白名单用户已存在
        if (baseMapper.selectListByUserNameOrMobile(bizCode, null, userName, mobile).size() > 0) {
            metaList.add(new Meta(Meta.CODE_451.getCode(), "白名单用户已存在"));
            return false;
        }
        //判断用户账号是否存在，不存在也应该上传
        Map queryMap = new HashMap();
        queryMap.put("user_name", userName);
        if (userBasicMapper.selectByMap(queryMap).size() == 0) {
            metaList.add(new Meta(Meta.CODE_451.getCode(), "用户帐号不存在"));
            return true;
        }
        //判断手机号缺失，可以导入
        if (StringUtils.isEmpty(mobile)) {
            metaList.add(new Meta(Meta.CODE_451.getCode(), "手机号缺失"));
            return true;
        }
        return true;
    }


    public void save(MngUserSafeImportReq userSafeImportReq, String userName, String mobile, String bizCode) {
        UserSafe userSafe = new UserSafe();
        userSafe.setBizCode(bizCode);
        userSafe.setUserName(userName);
        userSafe.setMobile(mobile);

        Map queryMap = new HashMap();
        queryMap.put("user_name", userName);
        List<UserBasic> userBasics = userBasicMapper.selectByMap(queryMap);
        if (userBasics.size() > 0) {
            UserBasic userBasic = userBasics.get(0);
            userSafe.setUserId(userBasic.getUserId());
        }

        userSafe.setSource(UserSafeSourceEnum.BACK_INPUT.getDbValue());
        userSafe.setStatus(UserSafeStatusEnum.APPROVED.getDbValue());
        userSafe.setCreatedTime(new java.util.Date());
        userSafe.setCreatedBy(userSafeImportReq.getUserId());
        userSafe.setModifiedTime(new Date());
        userSafe.setModifiedBy(userSafeImportReq.getUserId());
        userSafe.setOperator(userSafeImportReq.getOperator());
        insert(userSafe);
    }
}